#include "stdafx.h"

#include "afxmt.h"

#include <string.h>

#include "msgmng.h"
#include "protocol.h"
#include "netop.h"

static CHAR m_MsgBuf[PROTCOL_MAX_MSG_LEN * 2];
static INT m_iHead, m_iTail;

static BOOL MsgMngFindValidMsgHeader(VOID);
static BOOL MsgMngFindValidMsgBody(UCHAR *pMsg, INT *pMsgLen);
static VOID MsgMngAdjustMsgBuf(VOID);

BOOL MsgMngInit(VOID)
{
	memset(m_MsgBuf, 0, sizeof(m_MsgBuf));
	m_iHead = 0;
	m_iTail = 0;

	return (TRUE);
}

VOID MsgMngUninit(VOID)
{
}

static BOOL MsgMngFindValidMsgHeader(VOID)
{
	INT i, iSearchLen, iOffset;
	BOOL bRet;
	S_PROTOCOL_HEADER *pMsgHeader;

	iSearchLen = m_iTail - strlen(PROTOCOL_MAGIC_NUM);

	for (i = m_iHead; i < iSearchLen; i++)
	{
		if (!memcmp((void *)&m_MsgBuf[i], (void *)PROTOCOL_MAGIC_NUM, strlen(PROTOCOL_MAGIC_NUM)))
		{
			iOffset = i + sizeof(S_PROTOCOL_HEADER);
			if (iOffset > m_iTail)
			{
				m_iHead = i;
				return (FALSE);
			}
			
			pMsgHeader = (S_PROTOCOL_HEADER *)&m_MsgBuf[i];
			
			bRet = ProtocolIsHeaderValid((unsigned char *)pMsgHeader);
			if (TRUE != bRet)
			{
				continue;
			}

			m_iHead = i;
			return (TRUE);
		}
	}

	m_iHead = m_iTail = 0;

	return (FALSE);
}

static BOOL MsgMngFindValidMsgBody(UCHAR *pMsg, INT *pMsgLen)
{
	S_PROTOCOL_HEADER *pMsgHeader = (S_PROTOCOL_HEADER *)&m_MsgBuf[m_iHead];

	if (NULL == pMsg || NULL == pMsgLen)
	{
		exit(1);
	}
	
	if ((pMsgHeader->iLen + m_iHead) <= m_iTail)
	{
		memcpy((void *)pMsg, (void *)&m_MsgBuf[m_iHead], pMsgHeader->iLen);
		m_iHead += pMsgHeader->iLen;
		*pMsgLen = pMsgHeader->iLen;
		return (TRUE);
	}

	return (FALSE);
}

static VOID MsgMngAdjustMsgBuf(VOID)
{
	CHAR msgBuf[sizeof(m_MsgBuf)];

	memset(msgBuf, 0, sizeof(msgBuf));

	memcpy(msgBuf, &m_MsgBuf[m_iHead], m_iTail - m_iHead);
	memcpy(m_MsgBuf, msgBuf, m_iTail - m_iHead);

	m_iTail -= m_iHead;
	m_iHead = 0;
}

BOOL MsgMngRecvOneMsg(S_NET_CONNECT *pConDes, UCHAR *pMsg, INT *pMsgLen)
{
	BOOL bRet;
	INT iRcvLen;
	
	if (NULL == pMsg || NULL == pMsgLen)
	{
		exit(1);
	}

	bRet = NetTcpRecvASync(pConDes, &m_MsgBuf[m_iTail], (INT)(sizeof(m_MsgBuf) -
	  m_iTail), &iRcvLen);
	if (TRUE != bRet)
	{
		return (bRet);
	}

	m_iTail += iRcvLen;

	bRet = MsgMngFindValidMsgHeader();
	if (TRUE == bRet)
	{
		bRet = MsgMngFindValidMsgBody(pMsg, pMsgLen);
	}

	MsgMngAdjustMsgBuf();

	return (bRet);
}

BOOL MsgMngSendOneMsg(S_NET_CONNECT *pConDes, UCHAR *pMsg, INT iMsgLen)
{
	int iRet;

	iRet = NetTcpSend(pConDes, (char *)pMsg, iMsgLen);
	if (iRet >= 0)
	{
		return (TRUE);
	}
	else
	{
		return (FALSE);
	}
}
